/**
**********************************************************************************************************************************************************************************************************************************
* @file:	String.h
* @author:	zinface
* @date:	2021年09月11日 20:53:58 星期六
* @brief:	FinalC 提供的 String 数据类型操作集
* 
* 1. createString(): 创建空String
* 2. createStringWith_cstr: 基于给定的字符串创建 String 对象实例
* 3. createStringWith_copy_cstr: 基于给定的字符串拷贝创建 String 对象实例
* 4. createStringWith_size: 基于给定的容器大小创建 String 对象实例
* 
* 5. destroyString: 释放 String 对象
* 6. clearString: 清空 String 对象
* 7. deleteString: 销毁 String 对象

宗旨：为扩展
**********************************************************************************************************************************************************************************************************************************
**/
// #ifndef __STRING__H__
// #define __STRING__H__

#include "FinalCType/String.h"
#include "FinalCType/StringList.h"

// ------------------------------------ c_str utils
static char * c_str_copy(const char *str) {
    if (str == NULL) return NULL;

    int len = strlen(str);
    char* buffer = calloc(1, len+1);
    strcpy(buffer, str);

    return buffer;
}

static char* c_str_copy_expand_size(const char* str, int expand_size) {
    int len = str?strlen(str):0;

    char* buffer = calloc(1, expand_size+1);
    str?strcpy(buffer, str):0;

    return buffer;
}

static char* c_str_new(long size) {
    if (size > 0) {
        return malloc(size);
    }
    return NULL;
}

// ------------------------------------ c_str utils

// FinalC_Object_Define(String) {
//     char* value;
//     int len;
//     int allocated_len;
// };
FinalC_Object_Size(String);
#define self s->value

// ------------------------------------ Constructor

/**
 * createString(): 创建空String
 *
 */
FINALC_WARN_UNUSED_RESULT
FinalC_Object_Create_Define(String) {
    String *s = (String*)calloc(StringSize(), 1);
    self = c_str_new(s->len);
    s->len = 0;
    s->allocated_len = 0;
    return s;
}
/**
 * createStringWith_cstr: 基于给定的字符串创建 String 对象实例
 *
 */
// FinalC_Object_Create_With_Obj_Define(String, value, char);
FINALC_WARN_UNUSED_RESULT
String *createStringWith_cstr(char *str) {
    String *s = createString();
    self = str;
    s->len = strlen(self);
    return s;
}
/**
 * createStringWith_copy_cstr: 基于给定的字符串拷贝创建 String 对象实例
 *
 */
FINALC_WARN_UNUSED_RESULT
String *createStringWith_copy_cstr(const char *str) {
    String *s = createString();
    self = c_str_copy(str);
    s->len = strlen(self);
    return s;
}
/**
 * createStringWith_size: 基于给定的容器大小创建 String 对象实例
 *
 */
FINALC_WARN_UNUSED_RESULT
String *createStringWith_size(int size) {
    String *s = createString();
    self = c_str_new(size);
    s->len = size;
    return s;
}

// String *createStringWith_size(const char *str) {
//     String *s = createString();
//     s->value = c_str_copy(str);
//     s->len = strlen(s->value);
//     return s;
// }

// ------------------------------------ Destructor

/**
 * destroyString: 释放 String 对象
 * 
 * NOTE: 该对象指向的元素(如有)将不会进行释放，否则使用 deleteString()
 */
void destroyString(String *s) {
    if (s && self) self = NULL;
    if (s) free(s);
    if (s) s = NULL;
}
// FinalC_Object_After(String, destroy);

/**
 * clearString: 清空 String 对象
 * 
 * NOTE: 该对象指向的内存(如有)将会进行释放
 */
void clearString(String *s) {
    if (s && s->len) s->len = 0;
    if (s && self) free(self);
    if (s && self) self = NULL;
}

/**
 * deleteString: 销毁 String 对象
 * 
 * NOTE: 该对象指向的内存(如有)将会进行释放
 */
void deleteString(String *s) {
    // if (s && s->value) free(s->value);
    clearString(s);
    destroyString(s);
}
// FinalC_Object_After(String, delete);

// ------------------------------------ Exstenstion Func: Append

/**
 * stringAppend_cstr: 向 String 对象追加内容
 *
 * return: 返回 String 对象
 */
String *stringAppend_cstr(String *s, const char *str) {
    if (!s) s = createString();

    String *v = createStringWith_cstr((char*)str);

    if (v->len) {
        char * c_str = self;
        
        s->len = v->len + s->len;
        self = c_str_copy_expand_size(self, s->len);
        strcat(self, v->value);

        free(c_str);
    }

    destroyString(v);

    return s;
}
#include <stdarg.h>
static String *stringAppend_cstr_valist(String *s, char *str, va_list vlist) {
    while (str) {
        s = stringAppend_cstr(s, str);
        str = va_arg(vlist, char *);
    }
    return s;
}

String *stringAppend_cstrs(String *s, char *str, ...) {
    va_list vlist;
    va_start(vlist, str);
    s = stringAppend_cstr_valist(s, str, vlist);
    va_end(vlist);
    return s;
}

// String *stringAppend_delete(String *s, String *v) {
//     s = stringAppend_cstr(s, v->value);
//     deleteString(v);
//     return s;
// }

/**
 * stringAppend_char: 向 String 对象追加内容
 *
 * return: 返回 String 对象
 */
String *stringAppend_char(String *s, char c) {
    char val[2] = {c, 0};
    return stringAppend_cstr(s, val);
}

String *stringAppend(String *s, String *v) {
    return stringAppend_cstr(s, v->value);
}

// ------------------------------------ Exstenstion Func: Compare

bool stringCompare_cstr(String *s, const char *v) {
    return (s->len == strlen(v) && strncmp(self, v, strlen(v)) == 0);
}
bool stringCompare(String *s, String *v) {
    return (s->len == v->len && strncmp(self, v->value, v->len) == 0);
}

// ------------------------------------ Exstenstion Func: Contains

bool stringContains(String *s, String *v) {
    for (int i = 0; i < s->len; i++) {
        if (strlen(self + i)>=v->len && strncmp(self + i, v->value, v->len) == 0)
            return true;
    }
    return false;
}

bool stringContains_cstr(String *s, const char *v) {
    bool contain = false;
    String *temp = createStringWith_cstr((char*)v);

    contain = stringContains(s, temp); 
    destroyString(temp);

    return contain;
}
bool stringContains_char(String *s, const char v) {
    char temp[] = {v, 0};
    return stringContains_cstr(s, temp);
}

// ------------------------------------ Exstenstion Func: Split
List* stringSplit(const String *s, char value) {
    // printf("%s - 进入\n", __FUNCTION__);
    List *list = NULL;
    char *p = NULL;
    char *start_of_word = NULL;

    if (self == NULL) return NULL;

    String *temp = createStringWith_copy_cstr(self);
    
    p = temp->value;
    start_of_word = p;

    for (; *p != 0; p++)
    {
        if (*p == value) {
            *p = 0;
            list = listAppend(list, createStringWith_copy_cstr(start_of_word));
            start_of_word = p+1;
            continue;
        }
    }

    if (strlen(start_of_word) > 0) {
        list = listAppend(list, createStringWith_copy_cstr(start_of_word));
    }

    deleteString(temp);
    
    // printf("%s - 出去\n", __FUNCTION__);
    return list;
}


List* stringSplits(const String *s, const char *value) {
    List *list = NULL;

    char *p = NULL;
    char *start_of_word = NULL;

    if (self == NULL) return NULL;

    String *temp = createStringWith_copy_cstr(self);
    
    p = temp->value;
    start_of_word = p;

    for (; *p != '\0'; )
    {
        if (strlen(p) >= strlen(value) && strncmp(p, value, strlen(value)) == 0) {
            *(p) = 0;
            list = listAppend(list, createStringWith_copy_cstr(start_of_word));
            start_of_word = p + strlen(value);
            p += strlen(value);
        } else {
            p++;
        }
    }

    if (strlen(start_of_word) > 0) {
        list = listAppend(list, createStringWith_copy_cstr(start_of_word));
    }

    deleteString(temp);
    
    // printf("%s - 出去\n", __FUNCTION__);
    return list;
}

List* stringSplit_cnt(const String *s, const char value, int cnt) {
    List *list = NULL;
    char *p = NULL;
    char *start_of_word = NULL;
    int split_cnt = cnt;

    if (self == NULL) return NULL;

    String *temp = createStringWith_copy_cstr(self);

    p = temp->value;
    start_of_word = p;

    for (; *p != 0 && split_cnt != 0; p++)
    {
        if (*p == value) {
            *p = 0;
            list = listAppend(list, createStringWith_copy_cstr(start_of_word));
            start_of_word = p+1;
            split_cnt--;
            continue;
        }
    }

    if (strlen(start_of_word) > 0) {
        list = listAppend(list, createStringWith_copy_cstr(start_of_word));
    }

    deleteString(temp);
    
    // printf("%s - 出去\n", __FUNCTION__);
    return list;
}

// StringList *stringSplit(String *s, String *v) {
    
// }

// ------------------------------------ Exstenstion Func: Replace

String *stringReplace(String *s, const char *old, const char *replate) {
// String *stringReplace(const char *buf, const char *old, const char *replace) {

    if (!stringCompare_cstr(s, old)) {
        return s;
    }
    
    // GSList *list = splits(buf, old);
    StringList *array = createStringListWithSplitsAfter(s, old, clearString);
    StringList *iter;
    stringlist_foreach(iter, array) {
        s = stringAppend(s, convString(iter->string));
        if (iter->next != stringListLast(array)) s = stringAppend_cstr(s, replate);
    }
    deleteStringList(array);
    return s;
}

/**
 * newString: 创建 String 对象，扩展 init 大小，并填充 init 值
 *
 */
// String* newString(const fchar *init) {
//     String *string;
//     if (init == NULL || *init == '\0') {
//         string = createString();
//     } else {
//         fint len = strlen(init);
//         string = createString();
//         string->value = createBufferCopy(init);
//         string->len = len;
//     }
//     return string;
// }

/**
 * newStringSize: 创建 String 对象，扩展 size 大小，并填充 init 值
 *
 */
// String* newStringSize(const fchar *init, int size) {
//     String *string;
//     if (init == NULL || *init == '\0') {
//         string = createString();
//     } else {
//         fint len = strlen(init);
//         string = createString();
//         string->value = createBufferSizeCopy(init, size);
//         string->len = len;
//     }
//     return string;
// }

// #endif  //!__STRING__H__
